<?php

/**
 * 订单
 */

namespace app\admin\service;

use app\admin\model\Customer as CustomerModel;
use app\common\BusinessLog;
use app\common\Common;
use app\common\RabbitMQClient;
use app\common\RedisClient;
use Exception;
use setasign\Fpdi\PdfParser\Filter\Flate;
use think\facade\Db;
use app\admin\model\WholesalOrder as WholesalOrderModel;
use app\admin\model\Order as OrderModel;
use app\admin\model\Inventory as InventoryModel;
use app\admin\model\Address as AddressModel;
use app\admin\model\OrderItem as OrderItemModel;
use app\admin\model\WholesalOrderItem as WholesalOrderItemModel;
use think\facade\Config;
use app\common\ExchangeRateHostAPI;
use app\api\service\GoAffPro;
use app\common\service\CompleteNotificationService;
use think\facade\Log;
use app\admin\model\Images;
use app\admin\model\ProductPrice as PriceModel;

class WholesalOrder extends BaseService
{

    /**
     * 获取订单列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($param = [], $page = 1, $limit = 10)
    {
        $where[] = ['is_del', '=', 0];
        $where[] = ['order_category', '=', 'wholesal'];
        $arrData = ['code' => 0, 'message' => 'success'];

        if ($param['order_no']) {
            $where[] = ['order_no', 'like', '%' . $param['order_no'] . '%'];
        }

        if ($param['user_id']) {
            $where[] = ['user_id', 'in', $param['user_id']];
        }

        if ($param['status']) {
            $where[] = ['status', 'in', explode(',', $param['status'])];
        }
        if ($param['pay_status']) {
            $where[] = ['pay_status', 'in', explode(',', $param['pay_status'])];
        }
        if ($param['aftersales_status']) {
            $where[] = ['aftersales_status', 'in', explode(',', $param['aftersales_status'])];
        }
        if ($param['exceptionstatus']) {
            // exceptionstatus 模糊匹配：只要包含查询参数中的任意一个状态值即可
            $exceptionStatusArray = explode(',', $param['exceptionstatus']);
            $exceptionStatusArray = array_map('trim', $exceptionStatusArray); // 去除空格
            $exceptionStatusArray = array_unique($exceptionStatusArray); // 去重

            $conditions = [];
            foreach ($exceptionStatusArray as $status) {
                $conditions[] = "exceptionstatus LIKE '%{$status}%'";
            }
            $where[] = ['', 'exp', Db::raw('(' . implode(' OR ', $conditions) . ')')];
        }

        if ($param['start_time']) {
            $where[] = ['create_time', '>=', $param['start_time']];
        }
        if ($param['end_time']) {
            $where[] = ['create_time', '<', $param['end_time']];
        }
        if ($param['username']) {
            $userIds = Db::name('customer')->where([
                'is_del' => 0,
            ])->whereLike('cusname', '%' . $param['username'] . '%')->field('id')->select()->toArray();
            if (count($userIds)) {
                $where[] = ['user_id', 'in', implode(',', array_column($userIds, 'id'))];
            }
        }
        if (isset($param['id']) && !empty($param['id'])) {
            $where[] = ['id', '=', $param['id']];
        }

        $itemWhere = [];
        if (isset($param['product_id']) && $param['product_id']) {
            $itemWhere[] = ['product_id', 'in', $param['product_id']];
        }
        if (isset($param['warehouse_id']) && $param['warehouse_id']) {
            $itemWhere[] = ['warehouse_id', 'in', $param['warehouse_id']];
        }
        if (isset($param['is_futures']) && $param['is_futures'] !== null && $param['is_futures'] !== '') {
            $itemWhere[] = ['is_futures', '=', $param['is_futures']];
        }
        $oWholesalOrderModel = WholesalOrderModel::where($where)->whereIn('id', function ($query) use ($itemWhere) {
            $query->name('order_item')
                ->where('is_del', 0)
                ->where(function ($query) use ($itemWhere) {
                    if (count($itemWhere) > 0) {
                        $query->where($itemWhere);
                    }
                })
                ->field('order_id');
        });;

        $total = $oWholesalOrderModel->count();

        $field = [
            'id',
            'order_no',
            'user_id',
            'total_amount',
            'status',
            'pay_amount',
            'pay_status',
            'payment_method',
            'currency',
            'notes',
            'order_remark',
            'creator',
            'create_time',
            'updater',
            'update_time',
            'id_number',
            'signatory',
            'signing_date',
            'single_order_method',
            'contract_signing_status',
            'owner',
            'partner',
            'product_total_original_amount',
            'pay_terms',
            'review_node',
            'exceptionstatus',
            'aftersales_status'
        ];

        $result = $oWholesalOrderModel
            ->with(['customer', 'itemList'])
            ->field($field)
            ->order('id desc')
            ->page($page, $limit)
            ->select();
        $order_list = [];
        foreach ($result as &$value) {
            $value->user_email = $value->user_name . ' (' . $value->user_email . ')';
            $order_list[] = $value['id'];
        }


        $not_now = WholesalOrderItemModel::where('order_id', 'in', $order_list)
            ->where('is_del', 0)
            ->where('quantity', '>', 0)
            ->where('is_futures', '<>', 0)
            ->column('order_id');
        $data = $result->toArray();

        foreach ($data as &$item) {
            $item['show_entry'] = (in_array($item['id'], $not_now) && $item['pay_status'] == 3 && $item['review_node'] == 0);
            $item['buy_goods'] = [];
            if ($item['itemList']) {
                foreach ($item['itemList'] as $itemList) {
                    $enum = InventoryModel::getStaticEnum();
                    $is_futures_enum = $enum['is_futures'];
                    $item['buy_goods'][] = [
                        'warehouse_name' => $itemList['warehouse_name'],
                        'is_futures' => $is_futures_enum[$itemList['is_futures']],
                        'code' => $itemList['code'],
                        'quantity' => $itemList['quantity'],
                        'wholesal_id' => $itemList['wholesal_id']
                    ];
                }
            }
            unset($item['itemList']);
        }

        $arrData['data'] = ['list' => $data, 'total' => $total];
        return $arrData;
    }


    /**
     * 删除单条或多条订单数据
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete($param)
    {
        $where = [['is_del', '=', '0'], ['id', 'in', $param['ids']]];
        $oWholesalOrderModel = WholesalOrderModel::where($where);
        $category = $oWholesalOrderModel->find();
        if (!$category) {
            return ['code' => 1, 'message' => '获取订单信息失败！'];
        }
        $result = $oWholesalOrderModel->update(['is_del' => time()]);
        if ($result) {
            $this->logger->logOperation($param['ids'], 'order', '订单-删除', '删除资产订单');
            return ['code' => 0, 'message' => '删除订单成功！'];
        } else {
            return ['code' => 1, 'message' => '删除订单失败！'];
        }
    }

    /**
     * 添加修改订单
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function save($param)
    {
        $productList =  $param['product_list'];


        $conditions = [];
        foreach ($productList as $key => $item) {
            $conditions[$key]['productid'] = $item['product_id'];
            $conditions[$key]['wid'] = $item['wid'];
            $conditions[$key]['arrival_date'] = $item['arrival_date'];
            $conditions[$key]['is_futures'] = $item['is_futures'];
            $conditions[$key]['quantity'] = $item['pay_quantity'];
        }

        $ProductInventory = new ProductInventory();
        $inventory = $ProductInventory->inventory($conditions);


        /* 发生错误 */
        if ($inventory['code'] === 1) {
            return $inventory;
        }

        $isOversold = false;
        foreach ($inventory['data'] as $key => $item) {
            if ($item['exceed_quantity'] !== 0) {
                return ['code' => 1, 'message' => '數量超過庫存'];
            }
        }

        $inventoryData = [];
        foreach ($inventory['data'] as $item) {
            $inventoryData[implode('_', [
                $item['productid'],
                $item['wid'],
                $item['arrival_date'],
                $item['is_futures']
            ])] = $item;
        }

        foreach ($productList as $key => &$item) {
            $inventory_key =  implode('_', [
                $item['product_id'],
                $item['wid'],
                $item['arrival_date'],
                $item['is_futures']
            ]);
            $param['product_list'][$key]['inventory'] = $inventoryData[$inventory_key];
        }

        Db::startTrans();
        try {
            // 查询用户
            $oCustomerModel = CustomerModel::where('id', $param['user_id'])->find();
            if (!$oCustomerModel) {
                throw new Exception("客户不存在！");
            }
            $oCommon = new Common();
            if (isset($param['order_no']) && $param['order_no']) {
                $orderno = $param['order_no'];
            } else {
                $orderno = $oCommon->generateOrderNoNew($param['contract_type'], $param['owner']);
            }
            $total_num = 0;
            $total_amount = 0;
            $total_actual = 0;
            $share_arr = [];
            $total_first_leg_logistics_fee = 0; // 头程物流费
            foreach ($param['product_list'] as &$value) {
                $total_num += $value['pay_quantity'];
                $value['original_actual_selling_price'] = $this->getProductOriginalPrice($value, $value['actual_quoted_currency']);
                $original_price_sum = bcadd(bcmul((float)$value['original_actual_selling_price'], (int)$value['pay_quantity'], 2), $total_amount, 2);
                $value['original_price_sum'] = $original_price_sum;
                $total_amount = $original_price_sum; // 商品销售价 合计
                $actual_price_sum = bcadd(bcmul((float)$value['actual_selling_price'], (int)$value['pay_quantity'], 2), $total_actual, 2);
                $total_actual = $actual_price_sum; // 用户输入价格合计
                $value['actual_price_sum'] = $actual_price_sum;
                // 判断共享库存
                if (isset($value['share_id'])) {
                    $share_arr[$value['share_id']]['quantity'] = $value['quantity'];
                    $share_arr[$value['share_id']]['pay_quantity'] = $value['pay_quantity'] + (isset($share_arr[$value['share_id']]['pay_quantity']) ? $share_arr[$value['share_id']]['pay_quantity'] : 0);
                }
                $total_first_leg_logistics_fee = bcadd(
                    $total_first_leg_logistics_fee,
                    bcmul((string)($value['first_leg_logistics_fee'] ?? '0'), (string)($value['pay_quantity'] ?? '0'), 2),
                    2
                );
            }
            foreach ($share_arr as $item) {
                if ($item['quantity'] < $item['pay_quantity'] && $item['allow_zero_stock_sale'] == 0) {
                    return ['code' => 1, 'message' => '共享库存不足'];
                }
            }
            $oWholesalOrderModel = new WholesalOrderModel();
            $oWholesalOrderModel->order_no = $orderno;
            $oWholesalOrderModel->user_id = $param['user_id'];
            $oWholesalOrderModel->order_num = $total_num;
            $oWholesalOrderModel->creator = $param['operator_id'];
            $oWholesalOrderModel->status = 10; //待支付
            $oWholesalOrderModel->is_del = 0;
            $oWholesalOrderModel->creator = $param['operator_id'];
            $oWholesalOrderModel->create_time = date('Y-m-d H:i:s');
            $oWholesalOrderModel->is_del = 0;
            $oWholesalOrderModel->order_remark = $param['order_remark']; //订单备注
            $oWholesalOrderModel->pay_terms = 0;
            $oWholesalOrderModel->first_leg_logistics_fee = $total_first_leg_logistics_fee;
            $oWholesalOrderModel->total_amount = $total_actual + $total_first_leg_logistics_fee;
            $oWholesalOrderModel->pay_amount = 0; // 已付款金额
            $oWholesalOrderModel->pay_status = 1;
            $oWholesalOrderModel->product_total_amount = $total_actual;
            $oWholesalOrderModel->product_total_original_amount = $total_amount;
            $oWholesalOrderModel->currency = $param['currency'];
            $oWholesalOrderModel->order_category = 'wholesal';
            $oWholesalOrderModel->order_type = '1';

            // $oWholesalOrderModel->review_node = 4;

            $oWholesalOrderModel->signatory = $param['signatory'];
            $oWholesalOrderModel->signing_date = $param['signing_date'];
            $oWholesalOrderModel->single_order_method = $param['single_order_method'];
            $oWholesalOrderModel->id_number = $param['id_number'];
            $oWholesalOrderModel->payment_deadline = $param['payment_deadline'];
            $oWholesalOrderModel->shipping_start_date = $param['shipping_start_date'];
            if ($param['shipping_end_date']) {
                $oWholesalOrderModel->shipping_end_date = $param['shipping_end_date'];
            }
            $oWholesalOrderModel->transfer_payment_info = $param['transfer_payment_info'];
            $oWholesalOrderModel->contract_type = $param['contract_type'];
            $oWholesalOrderModel->owner = $param['owner'];
            $oWholesalOrderModel->partner = $param['partner'];
            $oWholesalOrderModel->order_num = array_sum(array_column($param['product_list'], 'pay_quantity'));
            $oWholesalOrderModel->pay_terms = $param['pay_terms'];
            $oWholesalOrderModel->advance_amount = $param['advance_amount'];
            $oWholesalOrderModel->source = $param['source'];
            $oWholesalOrderModel->is_sop = $param['is_sop']; // 是否拼单采购(Single Order Procurement) 0 - 否 1 - 是

            if (!$oWholesalOrderModel->save()) {
                throw new Exception("订单保存失败！");
            }
            $insert_data = [];

            foreach ($param['product_list'] as $item) {

                $original_price = $this->getProductOriginalPrice($item, $item['actual_quoted_currency']);

                $insert_data[] = [
                    'user_id' => $param['user_id'],
                    'order_id' => $oWholesalOrderModel->id,
                    'product_id' => $item['product_id'],
                    'warehouse_id' => $item['wid'],
                    'original_price' => $original_price,
                    'actual_price' => $item['actual_price'],
                    'quantity' => $item['pay_quantity'],
                    'creator' => $param['operator_id'],
                    'create_time' => date('Y-m-d H:i:s'),
                    'arrival_date' => $item['arrival_date'],
                    'real_arrival_date' => $item['real_arrival_date'],
                    'is_futures' => $item['is_futures'],
                    'lock_qty' => 0,
                    'transaction_currency_id' => $item['actual_quoted_currency'],
                    'price_selected_currency' => $item['actual_selling_price'],
                    'purchase_currency' => $item['inventory']['items'][0]['purchase_currency'],
                    'purchase_price' => $item['inventory']['items'][0]['purchase_price'],
                    'free_shipping' => $item['free_shipping'],
                    'apply_rules' => $item['apply_rules'],
                    'pending_quantity' => $item['pay_quantity'],
                    'first_leg_logistics_fee' => $item['first_leg_logistics_fee']
                ];
            }

            // 存入子表
            $result = WholesalOrderItemModel::insertAll($insert_data);
            if (!$result) {
                throw new Exception("订单明细保存失败！");
            }
            // 再锁定库存 新版本下单无需锁定库存
            // $apiOrder = new Inventory();
            // $apiOrder->Inventorylocking($oWholesalOrderModel, 'wholesale');
            // 更新客户表
            if ($oCustomerModel->stage != 3 && $oCustomerModel->stage != 2) {
                $oCustomerModel->stage = 2;
                if (!$oCustomerModel->save()) {
                    throw new Exception("客户状态更新失败！");
                }
            }
            // 记录日志
            $oBussinessLogService = new BusinessLog();
            $oBussinessLogService->logOperation($oWholesalOrderModel->id, 'order', '订单-创建', '经销商资产订单创建');
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }
        return ['code' => 0, 'message' => '保存订单成功！'];
    }


    /**
     * 获取产品原价 经销商原价是一级折扣价格
     * @param $role
     * @param $product
     * @return float
     */
    private function getProductOriginalPrice($product, $transactionCurrencyId)
    {
        $inventoryInfo = InventoryModel::getInventoryInfoByFourElements($product['arrival_date'], $product['wid'], $product['is_futures'], $product['product_id']);

        $price = PriceModel::getPriceFromInventory($inventoryInfo['id'], $product['wid'], $transactionCurrencyId);

        $original_price = array_reduce($price['discount'], function ($carry, $item) {
            return $item['level'] == 1 ? $item['price'] : $carry;
        }, 0);

        return $original_price;
    }


    /**
     * 获取单个订单信息
     * @param int $id 订单ID
     * @return array
     */
    public function getInfo($param)
    {

        $where[] = ['order_category', '=', 'wholesal'];
        $where[] = ['is_del', '=', '0'];
        $where[] = ['id', '=', $param['id']];

        $field = [
            'id',
            'order_no',
            'pay_terms',
            'advance_amount',
            'total_amount',
            'status',
            'pay_amount',
            'pay_status',
            'user_id',
            'notes',
            'order_remark',
            'creator',
            'create_time',
            'updater',
            'update_time',
            'signatory',
            'signing_date',
            'single_order_method',
            'contract_type',
            'currency',
            'id_number',
            'payment_deadline',
            'shipping_start_date',
            'contract_type',
            'transfer_payment_info',
            'owner',
            'partner',
            'review_node',
            'first_leg_logistics_fee',
            'source',
            'aftersales_status',
            'is_sop'
        ];

        $oWholesalOrderModel = WholesalOrderModel::where($where)->with([
            'products_list',
            'payment_list',
            'order_list',
            'logger',
            'customer'
        ])->field($field)->find();


        if (!$oWholesalOrderModel) {
            return ['code' => 1, 'message' => '获取订单信息失败！'];
        }
        $formatData['user'] = $oWholesalOrderModel->user_name . ' (' . $oWholesalOrderModel->user_email . ')';
        // 格式化
        $format_order = [];
        if ($oWholesalOrderModel->creator) $oWholesalOrderModel->creator = Db::name('operator')->where('id', $oWholesalOrderModel->creator)->value('nickname');
        if ($oWholesalOrderModel->updater)  $oWholesalOrderModel->updater = Db::name('operator')->where('id', $oWholesalOrderModel->updater)->value('nickname');


        if (214 != $oWholesalOrderModel->currency) {
            // 获取币种信息
            $currencyIds = [$oWholesalOrderModel->currency, 214]; // 客户选定的币种和美金
            $currencyData = Db::table('db_transaction_currency')
                ->whereIn('id', $currencyIds)
                ->field('abbr,name,id')
                ->select()
                ->toArray();
            $currencyData = array_column($currencyData, null, 'id');

            $customerPaymentCurrencyData = $currencyData[$oWholesalOrderModel->currency] ?? null;
            $usdCurrencyData = $currencyData[214] ?? null;
            $fetcher = new ExchangeRateHostAPI();
            $conversion_rate = $fetcher->getRate($usdCurrencyData['abbr'], $customerPaymentCurrencyData['abbr']);
            if (!is_numeric($conversion_rate)) {
                return ['code' => 1, 'message' => '汇率获取失败' . $conversion_rate];
            }
        } else {
            $conversion_rate = 0;
        }


        foreach ($oWholesalOrderModel->order_list as $value) {
            if ($value->orders && !isset($format_order[$value->order_id]) && $value->orders->pay_status == 3) {
                $format_order[$value->order_id] = [
                    'id' => $value->orders->id,
                    'order_no' => $value->orders->order_no,
                    'product_id' => $value->product_id,
                    'user_name' => $oWholesalOrderModel->user_name,
                    'shipping_address' => $value->orders->shipping_address,
                    'delivery_method' => $value->orders->delivery_method,
                    'logistics_fee' => $value->orders->logistics_fee
                ];
            }
        }

        if ($oWholesalOrderModel->payment_list) {
            $all_voucher_id = array_column($oWholesalOrderModel->payment_list->toArray(), 'transfer_voucher_id');
            $all_recepit_id = array_column($oWholesalOrderModel->payment_list->toArray(), 'transfer_recepit_id');
            $all_voucher_id = array_merge($all_voucher_id, $all_recepit_id);
            $all_voucher_id = implode(',', $all_voucher_id);
            $oImages = new Images();
            $all_voucher_url = $oImages->getImagesByIds($all_voucher_id);
            $all_voucher_url = array_column($all_voucher_url,  null, 'id');
        }

        foreach ($oWholesalOrderModel->payment_list as $item) {
            if ($item->transfer_voucher_id) { // 获取转账凭证
                $item->transfer_voucher_url = array_reduce(explode(',', $item->transfer_voucher_id), function ($carry, $item) use ($all_voucher_url) {
                    $carry[] = $all_voucher_url[$item] ?? '';
                    return $carry;
                }, []);
            }
            if ($item->transfer_recepit_id) {
                $item->transfer_recepit_url = array_reduce(explode(',', $item->transfer_recepit_id), function ($carry, $item) use ($all_voucher_url) {
                    $carry[] = $all_voucher_url[$item] ?? '';
                    return $carry;
                }, []);
            }
            $item->user_name = $oWholesalOrderModel->user_name;
        }

        foreach ($oWholesalOrderModel->products_list as $jer) {

            $discount_price = [];
            $discount_where = [['productid', '=', $jer['product_id']], ['is_futures', '=', $jer['is_futures']], ['arrival_date', '=', $jer['arrival_date']], ['is_del', '=', '0']];
            $oInventoryModel = InventoryModel::with(['product_price' => function ($query) use ($jer) {
                // 这里添加 product_price 表的查询条件
                $query->where('transaction_currency_id', $jer['actual_quoted_currency']);
            }])->where($discount_where)->whereRaw('FIND_IN_SET(? , wid) > 0', [$jer['wid']])->find();
            if (isset($oInventoryModel->product_price) && isset($oInventoryModel->product_price->discount)) {
                foreach ($oInventoryModel->product_price->discount as $yer) {
                    $discount_price[] = [
                        'num' => $yer['num'],
                        'rate' => $yer['rate'],
                        'price' => $yer['price'],
                        'level' => $yer['level'],
                        'discount_actual_selling_price' => $conversion_rate > 0 ? round($yer['price'] * $conversion_rate, 2) : $yer['price']
                    ];
                }
            }
            $jer->discount_price = $discount_price;
            $jer->unique = $jer['product_id'] . '_' . $jer['arrival_date'] . '_' . $jer['is_futures'] . '_' . $jer['wid'];

            $available = Db::table('db_inventory')
                ->where([
                    'productid' => $jer['product_id'],
                    'arrival_date' => $jer['arrival_date'],
                    'is_futures' => $jer['is_futures'],
                    'is_del' => 0,
                    'is_sale' => 1
                ])
                ->whereRaw('FIND_IN_SET(? , wid) > 0', [$jer['wid']])
                ->field("SUM(available_qty) - SUM(lock_qty) as available_sum , MAX(allow_zero_stock_sale) as allow_zero_stock_sale")
                ->find();
            $jer->pay_quantity = $jer->quantity;
            $jer->quantity = $available['available_sum'] < 0 ? 0 : $available['available_sum'];
            $jer->allow_zero_stock_sale = $available['allow_zero_stock_sale'];
            $jer->actual_quoted_currency_name = Db::table('db_transaction_currency')->where('id', $jer->actual_quoted_currency)->field('name')->find()['name'];
        }
        $oWholesalOrderModel->user_email = $oWholesalOrderModel->user_name . ' (' . $oWholesalOrderModel->user_email . ')';
        $oWholesalOrderModel->order_list = array_values($format_order);


        $orderItemType = [];
        foreach ($oWholesalOrderModel->products_list as $item) { // 前台是否显示库存类型转换
            if (0 == $item->product_id) {
                $item->product_name = $item->product_abbr;
            }

            if (0 != $item->is_futures && $item->pay_quantity > 0) {
                $orderItemType[] = $item->is_futures;
            }
        }

        $oWholesalOrderModel->show_entry = (in_array(1, $orderItemType) || in_array(2, $orderItemType)) && $oWholesalOrderModel->pay_status == 3 && $oWholesalOrderModel->review_node == 0; // 是否显示库存类型转换
        return ['code' => 0, 'message' => 'success', 'data' => $oWholesalOrderModel];
    }

    /**
     * 获取单个订单信息
     * @param int $id 订单ID
     * @return array
     */
    public function copy($param)
    {

        $where[] = ['order_category', '=', 'wholesal'];
        $where[] = ['is_del', '=', '0'];
        $where[] = ['id', '=', $param['id']];

        $field = [
            'id',

            'pay_terms',
            'advance_amount',
            'total_amount',
            'user_id',
            'notes',
            'order_remark',
            'creator',
            'create_time',
            'updater',
            'update_time',
            'signatory',
            'signing_date',
            'single_order_method',
            'contract_type',
            'currency',
            'id_number',
            'payment_deadline',
            'shipping_start_date',
            'contract_type',
            'transfer_payment_info',
            'owner',
            'partner',
            'source'
        ];

        $oWholesalOrderModel = WholesalOrderModel::where($where)->with([
            'products_list',
            'order_list',
            'customer'
        ])->field($field)->find();


        if (!$oWholesalOrderModel) {
            return ['code' => 1, 'message' => '获取订单信息失败！'];
        }
        $formatData['user'] = $oWholesalOrderModel->user_name . ' (' . $oWholesalOrderModel->user_email . ')';
        // 格式化
        $format_order = [];
        if ($oWholesalOrderModel->creator) $oWholesalOrderModel->creator = Db::name('operator')->where('id', $oWholesalOrderModel->creator)->value('nickname');
        if ($oWholesalOrderModel->updater)  $oWholesalOrderModel->updater = Db::name('operator')->where('id', $oWholesalOrderModel->updater)->value('nickname');


        if (214 != $oWholesalOrderModel->currency) {
            // 获取币种信息
            $currencyIds = [$oWholesalOrderModel->currency, 214]; // 客户选定的币种和美金
            $currencyData = Db::table('db_transaction_currency')
                ->whereIn('id', $currencyIds)
                ->field('abbr,name,id')
                ->select()
                ->toArray();
            $currencyData = array_column($currencyData, null, 'id');

            $customerPaymentCurrencyData = $currencyData[$oWholesalOrderModel->currency] ?? null;
            $usdCurrencyData = $currencyData[214] ?? null;
            $fetcher = new ExchangeRateHostAPI();
            $conversion_rate = $fetcher->getRate($usdCurrencyData['abbr'], $customerPaymentCurrencyData['abbr']);
            if (!is_numeric($conversion_rate)) {
                return ['code' => 1, 'message' => '汇率获取失败' . $conversion_rate];
            }
        } else {
            $conversion_rate = 0;
        }

        foreach ($oWholesalOrderModel->products_list as $jer) {

            $available = Db::table('db_inventory')
                ->where([
                    'productid' => $jer['product_id'],
                    'arrival_date' => $jer['arrival_date'],
                    'is_futures' => $jer['is_futures'],
                    'is_del' => 0,
                    'is_sale' => 1
                ])
                ->whereRaw('FIND_IN_SET(? , wid) > 0', [$jer['wid']])
                ->field("SUM(available_qty) - SUM(lock_qty) as available_sum , MAX(allow_zero_stock_sale) as allow_zero_stock_sale")
                ->find();
            if ($available['allow_zero_stock_sale'] == 0 && $available['available_sum'] <= 0) {
                continue;
            }
            $discount_price = [];
            $discount_where = [['productid', '=', $jer['product_id']], ['is_futures', '=', $jer['is_futures']], ['arrival_date', '=', $jer['arrival_date']], ['is_del', '=', '0']];
            $oInventoryModel = InventoryModel::with(['product_price' => function ($query) use ($jer) {
                // 这里添加 product_price 表的查询条件
                $query->where('transaction_currency_id', $jer['actual_quoted_currency']);
            }])->where($discount_where)->whereRaw('FIND_IN_SET(? , wid) > 0', [$jer['wid']])->find();
            if (isset($oInventoryModel->product_price) && isset($oInventoryModel->product_price->discount)) {
                foreach ($oInventoryModel->product_price->discount as $yer) {
                    $discount_price[] = [
                        'num' => $yer['num'],
                        'rate' => $yer['rate'],
                        'price' => $yer['price'],
                        'level' => $yer['level'],
                        'discount_actual_selling_price' => $conversion_rate > 0 ? round($yer['price'] * $conversion_rate, 2) : $yer['price']
                    ];
                }
            }
            $jer->discount_price = $discount_price;
            $jer->unique = $jer['product_id'] . '_' . $jer['arrival_date'] . '_' . $jer['is_futures'] . '_' . $jer['wid'];

            $jer->pay_quantity = $jer->quantity;
            $jer->quantity = $available['available_sum'] < 0 ? 0 : $available['available_sum'];
            $jer->allow_zero_stock_sale = $available['allow_zero_stock_sale'];
            $jer->actual_quoted_currency_name = Db::table('db_transaction_currency')->where('id', $jer->actual_quoted_currency)->field('name')->find()['name'];
        }
        $oWholesalOrderModel->user_email = $oWholesalOrderModel->user_name . ' (' . $oWholesalOrderModel->user_email . ')';
        $oWholesalOrderModel->order_list = array_values($format_order);


        $orderItemType = [];
        foreach ($oWholesalOrderModel->products_list as $item) { // 前台是否显示库存类型转换
            if (0 == $item->product_id) {
                $item->product_name = $item->product_abbr;
            }

            if (0 != $item->is_futures && $item->pay_quantity > 0) {
                $orderItemType[] = $item->is_futures;
            }
        }

        $oWholesalOrderModel->show_entry = (in_array(1, $orderItemType) || in_array(2, $orderItemType)) && $oWholesalOrderModel->pay_status == 3 && $oWholesalOrderModel->review_node == 0; // 是否显示库存类型转换
        return ['code' => 0, 'message' => 'success', 'data' => $oWholesalOrderModel];
    }


    /**
     * 修改订单
     * @param $param
     * @return array
     * 2024-11-12 16 52 56
     * author: jiang
     */
    public function update($param)
    {
        Db::startTrans();
        try {
            // 获取订单详情
            $where = [['is_del', '=', '0'], ['id', '=', $param['id']]];
            $oWholesalOrderModel = WholesalOrderModel::with('items')->where($where)->whereIn('status', [10, 30, 40])
                ->where('review_node', 0)->find();
            if (!$oWholesalOrderModel) {
                throw new Exception("订单不存在或当前订单状态不允许修改！");
            }
            // +++ 新增：经销商订单拦截 +++ [1](@ref)
            if ($oWholesalOrderModel->order_type == 2) {
                throw new Exception("经销商发货订单不允许修改");
            }

            // 释放锁定库存
            // $apiOrder = new Inventory();
            // $apiOrder->InventoryUnlocking($oWholesalOrderModel, 'wholesale');

            $originalWholesalOrder = clone $oWholesalOrderModel;
            $redis = new RedisClient();
            $key = 'update_original_data_id:' . $oWholesalOrderModel->id;
            $redis->set($key, json_encode($oWholesalOrderModel->toArray()));
            $total_num = 0;
            $total_amount = 0;
            $total_actual = 0;
            $total_first_leg_logistics_fee = 0;

            // +++ 修改点2：获取已发货数量 +++
            $shippedQtys = $this->getShippedQtys($oWholesalOrderModel->id);

            foreach ($param['product_list'] as &$value) {
                // +++ 修改点3：商品数量校验 +++
                $key = $value['product_id'] . '_' . $value['wid'];
                $shippedQty = $shippedQtys[$key] ?? 0;
                if ($value['pay_quantity'] < $shippedQty) {
                    throw new Exception("商品数量不能小于已发货量($shippedQty)");
                }

                $total_num += $value['pay_quantity'];
                $original_price_sum = bcadd(bcmul((float)$value['actual_selling_price'], (int)$value['pay_quantity'], 2), $total_amount, 2);
                $value['original_price_sum'] = $original_price_sum;
                $total_amount = $original_price_sum;
                $actual_price_sum = bcadd(bcmul((float)$value['actual_selling_price'], (int)$value['pay_quantity'], 2), $total_actual, 2);
                $total_actual = $actual_price_sum;
                $value['actual_price_sum'] = $actual_price_sum;
                $total_first_leg_logistics_fee = bcadd(
                    $total_first_leg_logistics_fee,
                    bcmul((string)($value['first_leg_logistics_fee'] ?? '0'), (string)($value['pay_quantity'] ?? '0'), 2),
                    2
                );
                $batchWhere = [
                    ['productid', '=', $value['product_id']],
                    ['arrival_date', '=', $value['arrival_date']],
                    ['is_futures', '=', $value['is_futures']],
                    ['is_del', '=', 0],
                    ['is_sale', '=', 1]
                ];
                // 查询可用库存
                $available = Db::table('db_inventory')
                    ->where($batchWhere)
                    ->whereRaw('FIND_IN_SET(? , wid) > 0', [$value['wid']])
                    ->field("SUM(available_qty) - SUM(lock_qty) as available_sum")
                    ->find();
                if ($value['pay_quantity'] > $available['available_sum'] && $value['allow_zero_stock_sale'] == 0) {
                    throw new Exception("库存不足！");
                }
            }

            // +++ 修改点4：金额校验 +++
            $newTotalAmount = $total_amount + $total_first_leg_logistics_fee;
            if ($newTotalAmount < $oWholesalOrderModel->pay_amount) {
                throw new Exception("订单金额不能小于已付款金额");
            }
            $order_no = '';
            if (isset($param['order_no']) && $param['order_no']) {
                $order_no = $param['order_no'];
            }
            if ($order_no) {
                $oWholesalOrderModel->order_no = $order_no;
            }
            $pay_status = 1;
            if ($originalWholesalOrder->pay_amount > 0 && $newTotalAmount <= $originalWholesalOrder->pay_amount) {
                $pay_status = 3;
            } elseif ($originalWholesalOrder->pay_amount > 0 && $newTotalAmount > $originalWholesalOrder->pay_amount) {
                $pay_status = 4;
            }

            $oWholesalOrderModel->user_id = $param['user_id'];
            $oWholesalOrderModel->order_num = $total_num;
            $oWholesalOrderModel->updater = $param['operator_id'];
            $oWholesalOrderModel->update_time = date('Y-m-d H:i:s');
            $oWholesalOrderModel->order_remark = $param['order_remark'];
            $oWholesalOrderModel->first_leg_logistics_fee = $total_first_leg_logistics_fee;
            $oWholesalOrderModel->total_amount = $newTotalAmount; // 使用校验后的新金额
            $oWholesalOrderModel->pay_amount = $originalWholesalOrder->pay_amount;
            $oWholesalOrderModel->pay_status = $pay_status;

            // +++ 修改点5：支付状态处理 +++
            $status = $oWholesalOrderModel->status;
            $review_node = '';
            if (in_array($oWholesalOrderModel->pay_status, [3, 4])) {
                $status = 20;
                $review_node = 2;
            }
            if ($review_node) {
                $oWholesalOrderModel->review_node = $review_node;
            }
            $oWholesalOrderModel->status = $status;

            $oWholesalOrderModel->product_total_amount = $total_actual;
            $oWholesalOrderModel->product_total_original_amount = $total_amount;
            $oWholesalOrderModel->pay_terms = $param['pay_terms'];
            $oWholesalOrderModel->advance_amount = $param['advance_amount'];
            $oWholesalOrderModel->currency = $param['currency'];
            $oWholesalOrderModel->signatory = $param['signatory'];
            $oWholesalOrderModel->signing_date = $param['signing_date'];
            $oWholesalOrderModel->owner = $param['owner'];
            $oWholesalOrderModel->partner = $param['partner'];
            $oWholesalOrderModel->single_order_method = $param['single_order_method'];
            $oWholesalOrderModel->id_number = $param['id_number'];
            $oWholesalOrderModel->payment_deadline = $param['payment_deadline'];
            $oWholesalOrderModel->shipping_start_date = $param['shipping_start_date'];
            if ($param['shipping_end_date']) {
                $oWholesalOrderModel->shipping_end_date = $param['shipping_end_date'];
            }
            $oWholesalOrderModel->transfer_payment_info = $param['transfer_payment_info'];
            $oWholesalOrderModel->contract_type = $param['contract_type'];
            $oWholesalOrderModel->order_num = array_sum(array_column($param['product_list'], 'pay_quantity'));
            $oWholesalOrderModel->source = $param['source'];
            $oWholesalOrderModel->is_sop = $param['is_sop']; // 是否拼单采购(Single Order Procurement) 0 - 否 1 - 是

            if (!$oWholesalOrderModel->save()) {
                throw new Exception("订单保存失败！");
            }

            $ins_data = [];
            $up_data = [];
            foreach ($param['product_list'] as $item) {
                $key = $item['product_id'] . '_' . $item['wid'];
                // +++ 修改点6：重算待发数量 +++
                $shippedQty = $shippedQtys[$key] ?? 0;

                $original_price = $this->getProductOriginalPrice($item, $item['actual_quoted_currency']);

                if (isset($item['id'])) {

                    $up_data = [

                        'user_id' => $param['user_id'],
                        'order_id' => $oWholesalOrderModel->id,
                        'product_id' => $item['product_id'],
                        'warehouse_id' => $item['wid'],
                        'original_price' => $original_price,
                        'actual_price' => $item['actual_price'],
                        'quantity' => $item['pay_quantity'],
                        'pending_quantity' => $item['pay_quantity'] - $shippedQty, // 动态计算
                        'creator' => $param['operator_id'],
                        'arrival_date' => $item['arrival_date'],
                        'real_arrival_date' => $item['real_arrival_date'],
                        'is_futures' => $item['is_futures'],
                        'transaction_currency_id' => $item['actual_quoted_currency'],
                        'price_selected_currency' => $item['actual_selling_price'],
                        'first_leg_logistics_fee' => $item['first_leg_logistics_fee']
                    ];

                    $item_ids[] = $item['id'];
                    Db::name('order_item')->where('id', (int)$item['id'])->update($up_data);
                } else {
                    $ins_data[] = [
                        'user_id' => $param['user_id'],
                        'order_id' => $oWholesalOrderModel->id,
                        'product_id' => $item['product_id'],
                        'warehouse_id' => $item['wid'],
                        'original_price' => $original_price,
                        'actual_price' => $item['actual_price'],
                        'quantity' => $item['pay_quantity'],
                        'pending_quantity' => $item['pay_quantity'],
                        'creator' => $param['operator_id'],
                        'create_time' => date('Y-m-d H:i:s'),
                        'arrival_date' => $item['arrival_date'],
                        'real_arrival_date' => $item['real_arrival_date'],
                        'is_futures' => $item['is_futures'],
                        'lock_qty' => 0,
                        'transaction_currency_id' => $item['actual_quoted_currency'],
                        'price_selected_currency' => $item['actual_selling_price'],
                        'first_leg_logistics_fee' => $item['first_leg_logistics_fee']
                    ];
                }
            }

            // 清空子表信息
            $DelOrderItem = OrderItemModel::where('order_id', $oWholesalOrderModel->id);
            if (count($item_ids) > 0) {
                $toDelete = $DelOrderItem->whereNotIn('id', $item_ids)->select();

                // +++ 删除前检查已发货量 +++ [8](@ref)
                foreach ($toDelete as $item) {
                    $key = $item['product_id'] . '_' . $item['warehouse_id'];
                    $shippedQty = $shippedQtys[$key] ?? 0;
                    if ($shippedQty > 0) {
                        throw new Exception("包含已发货商品不可删除");
                    }
                }

                $DelOrderItem->whereNotIn('id', $item_ids)->update(['is_del' => time()]);
            } else {
                $DelOrderItem->update(['is_del' => time()]);
            }

            /* 新增 Item  */
            if (count($ins_data) > 0) {
                WholesalOrderItemModel::insertAll($ins_data);
            }
            // 记录日志
            $this->logger->logOperation($oWholesalOrderModel->id, 'order', '订单-编辑', '修改资产订单',1,'order',$oWholesalOrderModel->i,'1,10');
            Db::commit();

            // 通知
            // 处理客户变更通知
            $notifications = [];

            // 负责人变更通知
            if ($oWholesalOrderModel->owner != $originalWholesalOrder->owner) {
                if ($originalWholesalOrder->owner == 0) {
                    // 添加负责人
                    $notifications[] = ['event' => 'order_owner_allocated', 'recipients' => [$oWholesalOrderModel->owner], 'log' => '订单添加负责人通知发送失败'];
                } else {
                    // 变更负责人 - 通知新负责人和原负责人
                    $notifications[] = ['event' => 'order_owner_allocated', 'recipients' => [$oWholesalOrderModel->owner], 'log' => '订单变更负责人通知发送失败'];
                    $notifications[] = ['event' => 'order_owner_transfer', 'recipients' => [$originalWholesalOrder->owner], 'log' => '订单变更负责人通知发送失败'];
                }
            }

            // 合作伙伴变更通知
            if ($oWholesalOrderModel->partner != $originalWholesalOrder->partner) {
                $partnerArr = array_map('intval', array_filter(array_unique(explode(',', $oWholesalOrderModel->partner . ',' . $originalWholesalOrder->partner))));
                $notifications[] = ['event' => 'order_partner_transfer', 'recipients' => $partnerArr, 'log' => '订单合作伙伴变更通知发送失败'];
            }

            $partnerArr = $oWholesalOrderModel->partner ? array_filter(explode(',', $oWholesalOrderModel->partner)) : [];
            $recipients = array_merge([$oWholesalOrderModel->owner], $partnerArr);
            // 订单修改
            $notifications[] = ['event' => 'order_edit', 'recipients' => $recipients, 'log' => '订单修改通知发送失败'];
            if ($oWholesalOrderModel->status == 20) {
                $notifications[] = ['event' => 'order_audit', 'recipients' => [], 'log' => '订单待审核发送失败', 'job' => '1,10'];
            }

            // 统一发送所有通知
            if (!empty($notifications)) {
                $notificationService = new CompleteNotificationService();
                foreach ($notifications as $notification) {
                    try {
                        $notificationService->send($notification['event'], $oWholesalOrderModel->toArray(), $notification['recipients'], '', $notification['job'] ?? '');
                    } catch (\Exception $e) {
                        Log::error($notification['log'] . ': ' . $e->getMessage() . ' 订单编号: ' . $oWholesalOrderModel->order_no . ' | 文件：' . $e->getFile() . ' | 行号：' . $e->getLine());
                    }
                }
            }
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }
        return ['code' => 0, 'message' => '保存订单成功！'];
    }

    // +++ 新增：获取已发货数量方法 +++ [3](@ref)
    private function getShippedQtys($orderId)
    {
        $shippedData = Db::name('logistics_order_item')
            ->alias('loi')
            ->join('logistics_order lo', 'loi.logistics_order_id = lo.id')
            ->where('loi.order_id', $orderId)
            ->where('lo.type', 1)
            ->where('lo.status', 1)
            ->field('product_id, number as shipped_qty,warehouse_id')
            ->select();

        $result = [];

        foreach ($shippedData as $item) {
            $key = $item['product_id'] . '_' . $item['warehouse_id'];
            if (!isset($result[$key])) {
                $result[$key] = 0;
            }
            $result[$key] += $item['shipped_qty'];
        }

        return $result;
    }

    /**
     * 下拉框选择接口
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getSelect()
    {
        $where[] = ['is_del', '=', 0];
        $arrData = ['code' => 0, 'message' => 'success'];

        $field = ['id', 'name'];
        $oWholesalOrderModel = WholesalOrderModel::where($where);
        $total = $oWholesalOrderModel->count();
        $result = $oWholesalOrderModel->field('id AS value,name as label')->select();
        $arrData['data'] = ['list' => $result->toArray(), 'total' => $total];
        return $arrData;
    }

    /**
     * 订单发货
     * @param $param
     * @return array
     * 2024-11-17 15 55 24
     * author: jiang
     */
    public function deliver($param)
    {
        Db::startTrans();
        try {
            $order_list = [];
            foreach ($param['list'] as $value) {
                // 获取子订单详情
                $whereItem = [
                    ['item.product_id', '=', $value['product_id']],
                    ['item.is_futures', '=', $value['is_futures']],
                    ['item.warehouse_id', '=', $value['wid']],
                    ['item.arrival_date', '=', $value['arrival_date']],
                    ['item.user_id', '=', $param['user_id']]
                ];
                $semiModel = Db::name('order_item')
                    ->alias('item')
                    ->join('db_order o', 'item.order_id = o.id')
                    ->where('o.order_category', '=', 'wholesal')
                    ->where('o.review_node', '=', 0)
                    ->where('o.status', '=', 100)
                    ->whereRaw('pending_quantity - lock_qty > 0')
                    ->where('item.is_del', '=', 0)
                    ->where($whereItem);

                $enable_deliver_sum = $semiModel->sum(Db::raw('pending_quantity - lock_qty'));

                //                $enable_deliver_sum = WholesalOrderItemModel::with('wholesal_order')->where($whereItem)->sum(Db::raw('quantity - lock_qty'));

                if ($value['ship_quantity'] > $enable_deliver_sum) {
                    throw new Exception($value['product_id'] . "发货数量大于可发货数量！");
                }
                $oWholesalOrderItemModel = $semiModel->order('item.id', 'asc')->field('*,item.id as item_id')->select();

                if (!$oWholesalOrderItemModel) {
                    throw new Exception($value['product_id'] . "订单明细不存在！");
                }

                $surplus = $value['ship_quantity']; // 剩余发货数量
                foreach ($oWholesalOrderItemModel as $item) {
                    // 修改发货数量
                    $data = $item;
                    if ($item['pending_quantity'] - $item['lock_qty'] >= $surplus) {
                        $update = [
                            'lock_qty' => $item['lock_qty'] + $surplus,
                        ];
                        $item['lock_qty'] = $item['lock_qty'] + $surplus;
                        $data['surplus'] = $surplus;
                        $order_list[] = $data;
                        if (!OrderItemModel::where('id', $item['item_id'])->whereRaw(' pending_quantity - lock_qty >= ? ', [$surplus])->update($update)) {
                            throw new Exception("订单明细更新失败！");
                        }
                        break;
                    } else {
                        $qty_num = $item['pending_quantity'] - $item['lock_qty'];
                        if ($qty_num == 0) {
                            continue;
                        }
                        $update = [
                            'lock_qty' =>  $item['pending_quantity'],
                        ];

                        $surplus = $surplus - $qty_num;
                        $data['surplus'] = $qty_num;
                        $order_list[] = $data;
                    }
                    if (!OrderItemModel::where('id', $item['item_id'])->whereRaw(' pending_quantity - lock_qty >= ? ', [$qty_num])->update($update)) {
                        throw new Exception("订单明细更新失败！");
                    }
                }
            }
            $item_ids  =  array_column($oWholesalOrderItemModel->toArray(), 'item_id');
            [$source, $owner] = $this->getOrderMessageForOrderNo($item_ids);
            if ($param['owner']) {
                $owner = $param['owner'];
            }
            // 插入订单表
            $insert_item_data = [];
            $oCommon = new Common();
            $orderno = $oCommon->generateOrderNoZc($owner);

            $oOrderModel = new OrderModel();
            $oOrderModel->order_no = $orderno;
            $oOrderModel->user_id = $param['user_id'];
            $oOrderModel->notes = $param['notes'];
            $oOrderModel->order_remark = $param['order_remark'];
            $oOrderModel->order_type = 2;
            $oOrderModel->source = 0;
            $oOrderModel->owner = $owner;
            $oOrderModel->partner = $param['partner'];
            $oOrderModel->logistics_fee = 0.00;
            $oOrderModel->delivery_method = $param['delivery_method'];
            $oOrderModel->order_category = 'order';

            /* 添加账单地址 */
            if (!empty($param['billing_address_id'])) {

                $billingAddress = AddressModel::where('id', $param['billing_address_id'])->find();
                if (!$billingAddress) {
                    throw new Exception("账单地址不存在！");
                }

                $oOrderModel->billing_address_id = $billingAddress->id;
                $oOrderModel->billing_first_name = $billingAddress->first_name;
                $oOrderModel->billing_last_name = $billingAddress->last_name;
                $oOrderModel->billing_email = $billingAddress->email;
                $oOrderModel->billing_phone = $billingAddress->phone;
                $oOrderModel->billing_country_id = $billingAddress->country_id;
                $oOrderModel->billing_city_id = $billingAddress->city_id;
                $oOrderModel->billing_country_name = $billingAddress->country_name;
                $oOrderModel->billing_city_name = $billingAddress->city_name;
                $oOrderModel->billing_zip_code = $billingAddress->zip_code;
                $oOrderModel->billing_state = $billingAddress->state;
                $oOrderModel->billing_state_id = $billingAddress->state_id;
                $oOrderModel->billing_company = $billingAddress->company;
                $oOrderModel->billing_address = $billingAddress->address;
                $oOrderModel->billing_address2 = $billingAddress->address2;
                $oOrderModel->billing_remark = $billingAddress->billing_remark;
            }

            if ($param['delivery_method'] == 1) {

                $oAddressModel = AddressModel::where('id', $param['address_id'])->find();
                if (!$oAddressModel) {
                    throw new Exception("地址不存在！");
                }
                $oOrderModel->first_name = $oAddressModel->first_name;
                $oOrderModel->last_name = $oAddressModel->last_name;
                $oOrderModel->email = $oAddressModel->email;
                $oOrderModel->phone = $oAddressModel->phone;
                $oOrderModel->country_id = $oAddressModel->country_id;
                $oOrderModel->city_id = $oAddressModel->city_id;
                $oOrderModel->country_name = $oAddressModel->country_name;
                $oOrderModel->city_name = $oAddressModel->city_name;
                $oOrderModel->zip_code = $oAddressModel->zip_code;
                $oOrderModel->state = $oAddressModel->state;
                $oOrderModel->state_id = $oAddressModel->state_id;
                $oOrderModel->company = $oAddressModel->company;
                $oOrderModel->address = $oAddressModel->address;
                $oOrderModel->address2 = $oAddressModel->address2;
                $oOrderModel->address_id = $param['address_id'];
                $oOrderModel->logistics_fee = $param['logistics_fee'];
                $oOrderModel->delivery_remark = $oAddressModel->delivery_remark;
            } else {
                $oOrderModel->pickup_name = $param['name'];
                $oOrderModel->pickup_phone = $param['phone'];
                $oOrderModel->pickup_passport = $param['passport'];
                if ($param['delivery_method'] == 2) {
                    $oOrderModel->warehouse_code = $param['warehouse_code'];
                }
                if ($param['delivery_method'] == 0) {
                    $oOrderModel->pickup_vehicle = $param['vehicle'];
                    $oOrderModel->pickup_code = generateUniqueString(6);
                }
            }
            $oOrderModel->shipping_time = date('Y-m-d H:i:s');
            $oOrderModel->create_time = date('Y-m-d H:i:s');
            $oOrderModel->prescription = $param['prescription'];
            $oOrderModel->freight_collect = $param['freight_collect'] ? 1:0;
            $oOrderModel->total_amount = $param['logistics_fee'] ?? 0;
            $oOrderModel->pay_amount = 0;
            $oOrderModel->pay_status = 1;
            $oOrderModel->creator = $param['operator_id'];
            $oOrderModel->status = 10; // 待支付
            if ($param['delivery_method'] == 0 || $param['delivery_method'] == 2 || $param['freight_collect'] == true) {
                $oOrderModel->status = 30;
                $oOrderModel->pay_status = 3;
            }
            if (!$oOrderModel->save()) {
                throw new Exception("订单保存失败！");
            }
            $oBussinessLogService = new BusinessLog();

            foreach ($order_list as $jer) {

                $insert_item_data[] = [
                    'user_id' => $jer['user_id'],
                    'order_id' => $oOrderModel->id,
                    'product_id' => $jer['product_id'],
                    'warehouse_id' => $jer['warehouse_id'],
                    'original_price' => $jer['original_price'],
                    'actual_price' => $jer['actual_price'],
                    'quantity' => $jer['surplus'],
                    'pending_quantity' => $jer['surplus'],
                    'creator' => $param['operator_id'],
                    'create_time' => date('Y-m-d H:i:s'),
                    'wholesal_id' => $jer['id'],
                    'arrival_date' => $jer['arrival_date'],
                    'is_futures' => $jer['is_futures'],
                    'free_shipping' => $jer['free_shipping'],
                    'apply_rules' => $jer['apply_rules'],
                    'is_advance' => $jer['is_advance'],
                    'advance_ratio' => $jer['advance_ratio'],
                    'transaction_currency_id' => $jer['transaction_currency_id'],
                    'price_selected_currency' => $jer['price_selected_currency'],
                    'purchase_currency' => $jer['purchase_currency'],
                    'purchase_price' => $jer['purchase_price'],
                ];
            }
            $result = OrderItemModel::insertAll($insert_item_data);
            if (!$result) {
                throw new Exception("订单明细保存失败！");
            }
            //            // 压入队列
            //            $delaySecondsA = Config::get('system.back_locked_inventory'); // 延迟 5 秒
            //            $queueNameA = 'ordinaryQueueOrderCreate_' . $delaySecondsA; // 普通队列名称 订单创建审核
            //            $messageA = json_encode([
            //                'id' => $oOrderModel->id,
            //                'order_type' => 'wholesale',
            //                'status' => 10, // 10:创建订单 21:审核通过
            //                'queue_type' => 1 // 1:创建，审核订单 2:上传支付凭证
            //            ]);
            //            $rabbitMQService = new RabbitMQClient();
            //            $result1 = $rabbitMQService->sendDelayedMessage($queueNameA, $delaySecondsA, $messageA);
            $oBussinessLogService->logOperation($oOrderModel->id, 'order', '订单-发货', '经销商订单发货');
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }
        return ['code' => 0, 'message' => '订单发货成功！'];
    }
    private function getOrderMessageForOrderNo($ids)
    {
        $source = 1;
        $owner = 0;
        $order = Db::name('order_item')
            ->alias('item')
            ->join('db_order o', 'item.order_id = o.id')
            ->where('item.id', 'in', $ids)
            ->field('o.*')->group('item.order_id')->select()->toArray();
        if ($order) {
            foreach ($order as $o) {
                if ($o['owner']) {
                    $owner = $o['owner'];
                }
                if ($source == 2) {
                    continue;
                }
                if ($o['owner'] || $o['contract_type'] == 2 || stripos($o['order_no'], 'HK') !== false) {
                    $source = 2;
                }
            }
        }
        return [$source, $owner];
    }
    /**
     * 订单审核
     * @param $param
     * @return array|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-11-22 15 37 42
     * author: jiang
     */
    public function examine($param)
    {
        $where = [
            ['id', '=', $param['id']],
            ['status', '=', 20],
            ['is_del', '=', 0],
            ['pay_status', '=', 1]
        ];
        $oWholesalOrderModel = WholesalOrderModel::where($where)->find();
        if (!$oWholesalOrderModel) {
            return ['code' => 1, 'message' => '数据不存在！'];
        }
        switch ($oWholesalOrderModel->review_node) {
            case 1:
                return ['code' => 1, 'message' => '库存不足！'];
                break;
            case 4:
                $oWholesalOrderModel->status = 21;
                $oWholesalOrderModel->review_node = 0;
                if (!$oWholesalOrderModel->save()) {
                    return ['code' => 1, 'message' => '审核失败！'];
                }
                $oBussinessLogService = new BusinessLog();
                $oBussinessLogService->logOperation($oWholesalOrderModel->id, 'wholesal_order', '订单审核', '创建订单审核通过');
                break;
            case 2:
                $oWholesalOrderModel->status = 21;
                $oWholesalOrderModel->review_node = 0;
                if (!$oWholesalOrderModel->save()) {
                    return ['code' => 1, 'message' => '审核失败！'];
                }
                $oBussinessLogService = new BusinessLog();
                $oBussinessLogService->logOperation($oWholesalOrderModel->id, 'wholesal_order', '订单审核', '更新订单审核通过');
                break;
            case 3:
                return ['code' => 1, 'message' => '收货地址审核失败！'];
                break;
            default:
                return ['code' => 1, 'message' => '审核失败！'];
        }
        // 压入队列
        $delaySecondsA = Config::get('system.back_locked_inventory'); // 延迟 5 秒
        $queueNameA = 'ordinaryQueueOrderCreate_' . $delaySecondsA; // 普通队列名称 订单创建审核
        $messageA = json_encode([
            'id' => $oWholesalOrderModel->id,
            'order_type' => 'wholesale',
            'status' => 21, // 10:创建订单 21:审核通过
            'queue_type' => 1 // 1:创建，审核订单 2:上传支付凭证
        ]);
        $rabbitMQService = new RabbitMQClient();
        $result1 = $rabbitMQService->sendDelayedMessage($queueNameA, $delaySecondsA, $messageA);
        // $oBussinessLogService->logOperation($oWholesalOrderModel->id, 'wholesal_order', '订单审核', '订单审核');

        return ['code' => 0, 'message' => '审核成功！'];
    }

    /**
     * 枚举
     * @param $field
     * @return array
     * 2024-11-07 15 26 36
     * author: jiang
     */
    public function getFieldEnum($field)
    {
        $model = new WholesalOrderModel();
        $res = $model->getFieldEnum($field);
        return [
            'code' => 0,
            'data' => $res,
            'message' => '成功'
        ];
    }

    /**
     * 取消订单
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2025-03-11 14 40 39
     * author: jiang
     */
    public function cancel($param)
    {
        $order = WholesalOrderModel::where([['id', '=', $param['id']], ['status', '=', 10]])->find();
        if (!$order) {
            return ['code' => 1, 'message' => '订单不存在或状态不正确'];
        }

        Db::startTrans();
        try {
            if ($order->pay_status == 4 && $order->review_node != 1) { // review_node 为 1 时没有锁定库存，无需释放
                // 释放库存
                $items = $order->items->toArray();
                if (empty($items)) {
                    throw new \Exception('订单商品不存在');
                }
                $condition = [];
                foreach ($items as $item) {
                    $condition[] = [
                        'productid' => $item['product_id'],
                        'wid' => $item['warehouse_id'],
                        'arrival_date' => $item['arrival_date'],
                        'is_futures' => $item['is_futures'],
                        'quantity' => $item['quantity']
                    ];
                }
                $oProductInventory = new ProductInventory();
                $result = $oProductInventory->inventory($condition);
                if ($result['code'] === 1) {
                    return $result;
                }
                $data = $result['data'];
                if (!$data) {
                    throw new \Exception('未找到库存数据');
                }
                $inventorySet = [];
                foreach ($data as $value) {
                    //            if ($value['exceptionstatus'] == 1) {
                    //                return ['code' => 1, 'message' => '库存不足'];
                    //            }
                    foreach ($value['items'] as $val) {
                        $inventorySet[$val['id']] = $val['pay_quantity'];
                    }
                }
                // 获取库存信息
                $oInventoryModel = InventoryModel::whereIn('id', array_keys($inventorySet))->select();
                foreach ($oInventoryModel as $inv) {
                    // 锁定库存
                    $inv->lock_qty = $inv->lock_qty - $inventorySet[$inv->id] ?? 0;
                    if (!$inv->save()) {
                        throw new \Exception('库存释放失败');
                    }
                }
            }
            // 更新订单状态
            $order->status = 70;
            $order->updater = $param['operator_id'];
            $order->update_time = date('Y-m-d H:i:s');
            if (!$order->save()) {
                throw new \Exception('订单状态更新失败');
            }

            // 创建退货退款单
            if ($order->pay_status == 4) {
                $products = WholesalOrderItemModel::where('order_id', $order->id)->column('id,quantity as return_quantity,product_id,warehouse_id,quantity');
                if (count($products) == 0) {
                    throw new \Exception('订单商品不存在');
                }
                $formatProducts = [];
                foreach ($products as $value) {
                    // 更新判断库存
                    //                Warehouse::productSoldStat($value['product_id'],$value['warehouse_id'],0,0 - $value['quantity'],0);
                    $formatProducts[] = [
                        'id' => $value['id'],
                        'return_quantity' => $value['return_quantity']
                    ];
                }
                $oCustomerModel = CustomerModel::where('id', $order->user_id)->find();
                if (!$oCustomerModel) {
                    throw new \Exception('客户不存在');
                }

                $is_have_returnorder = Db::name('returnorder')->where('order_id', $order->id)->where('status', '<>', 4)->find();
                if (!$is_have_returnorder) {
                    $args = [];
                    $args['creator'] = $param['operator_id'];
                    $args['returnorder_type'] = 1;
                    $args['customer_id'] = $order->user_id;
                    $args['order_type'] = 'wholesale';
                    $args['order_id'] = $order->id;
                    $args['product'] = $formatProducts;
                    $args['signatory'] = $param['operator_id'];
                    $args['signing_date'] = date('Y-m-d');
                    $args['owner'] = $oCustomerModel->owner;
                    $args['partner'] = [];
                    $args['total_amount'] = $order->pay_amount;
                    $args['return_reason'] = 4;
                    $args['remark'] = null;
                    $args['operator_id'] = $param['operator_id'];
                    $service = new Returnorder();
                    $result = $service->save($args);
                    if ($result['code'] !== 0) {
                        throw new \Exception($result['message']);
                    }
                }
            }
            $this->logger->logOperation($param['id'], 'order', '订单-取消', '取消资产订单');
            Db::commit();

            $notificationService = new CompleteNotificationService();
            try {
                $partnerArr = $order->partner ? array_filter(explode(',', $order->partner)) : [];
                $recipients = array_merge([$order->owner, $order->signatory, ...$partnerArr]);
                $notificationService->send('order_cancel', $order->toArray(), $recipients);
            } catch (\Exception $e) {
                Log::error('订单取消通知失败: ' . $e->getMessage() . ' 订单编号: ' . $order->order_no . ' 文件：' . $e->getFile() . ' | 行号：' . $e->getLine());
            }
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }
        if ($order->status == 70) {
            /* 修改GoAffPro订单状态 */
            $GoAffPro = new GoAffPro();
            $GoAffPro->updateAffiliateOrder(false, $order->id);
        }
        return ['code' => 0, 'message' => 'success'];
    }
}
